﻿using AutoMapper;
using DFGK.IRepository;
using DFGK.IService;
using DFGK_WMS.Common;
using DFGK_WMS.Model.Dto;
using DFGK_WMS.Model.Enum;
using DFGK_WMS.Model.Models;
using DFGK_WMS.Model.Wcs;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.Extensions.Logging;
using NPOI.SS.UserModel.Helpers;
using System.Threading.Tasks;
using Yitter.IdGenerator;

namespace DFGK.Service
{
    public class ShippingOrderDetailService : BaseService, IShippingOrderDetailService
    {
        private readonly IReceivingOrderDetailRepository _receivingOrderDetailRepository;
        private readonly IShippingOrderDetailRepository _shippingOrderDetailRepository;
        private readonly IPickingOrderDetailRepository _pickingOrderDetailRepository;
        private readonly IPutawayOrderDetailRepository _putawayOrderDetailRepository;
        private readonly IInventoryDetailRepository _inventoryDetailRepository;
        private readonly IShippingLockCellRepository _lockCellRepository;
        private readonly IPutawayOrderRepository _putawayOrderRepository;
        private readonly IPickingOrderRepository _pickingOrderRepository;
        private readonly IInventoryLogRepository _inventoryLogRepository;
        private readonly IInterfaceLogRepository _interfaceLogRepository;
        private readonly IStationRepository _stationRepository;
        private readonly ILogger<ShippingOrderDetailService> logger;
        private readonly IWarehouseRepository _warehouseRepository;
        private readonly IInventoryRepository _inventoryRepository;
        private readonly ISupplierRepository _supplierRepository;
        private readonly ICustomerRepository _customerRepository;
        private readonly IRoutewayRepository _routewayRepository;
        private readonly IInstructRepository _instructRepository;
        private readonly IMaterialRepository _materialRepository;
        private readonly IPalletRepository _palletRepository;
        private readonly IShelfRepository _shelfRepository;
        private readonly IAreaRepository _areaRepository;
        private readonly ICellRepository _cellRepository;
        private readonly IUnitOfWork _unitOfWork;
        private readonly WcsHttpClient wcsHttp;

        public ShippingOrderDetailService(IMapper mapper, IShippingOrderDetailRepository _shippingOrderDetailRepository, IInventoryRepository inventoryRepository, IShippingLockCellRepository lockCellRepository, ISupplierRepository _supplierRepository, ICustomerRepository _customerRepository, IWarehouseRepository _warehouseRepository, IAreaRepository _areaRepository, IMaterialRepository _materialRepository, IUnitOfWork unitOfWork, ICellRepository cellRepository, IInstructRepository _instructRepository, IPickingOrderRepository _pickingOrderRepository, IPickingOrderDetailRepository _pickingOrderDetailRepository, IPalletRepository _palletRepository, IInventoryLogRepository _inventoryLogRepository, IInventoryDetailRepository inventoryDetailRepository, IPutawayOrderRepository putawayOrderRepository, IPutawayOrderDetailRepository _putawayOrderDetailRepository, ILogger<ShippingOrderDetailService> logger, WcsHttpClient wcsHttp, IShelfRepository _shelfRepository, IRoutewayRepository _routewayRepository, IReceivingOrderDetailRepository _receivingOrderDetailRepository, IInterfaceLogRepository _interfaceLogRepository, IStationRepository _stationRepository) : base(mapper)
        {
            this._receivingOrderDetailRepository = _receivingOrderDetailRepository;
            this._shippingOrderDetailRepository = _shippingOrderDetailRepository;
            this._pickingOrderDetailRepository = _pickingOrderDetailRepository;
            this._putawayOrderDetailRepository = _putawayOrderDetailRepository;
            this.logger = logger;
            this.wcsHttp = wcsHttp;
            this._pickingOrderRepository = _pickingOrderRepository;
            this._inventoryLogRepository = _inventoryLogRepository;
            this._interfaceLogRepository = _interfaceLogRepository;
            this._stationRepository = _stationRepository;
            this._warehouseRepository = _warehouseRepository;
            this._supplierRepository = _supplierRepository;
            this._customerRepository = _customerRepository;
            this._materialRepository = _materialRepository;
            this._instructRepository = _instructRepository;
            this._routewayRepository = _routewayRepository;
            this._shelfRepository = _shelfRepository;
            this._palletRepository = _palletRepository;
            this._areaRepository = _areaRepository;
            _inventoryDetailRepository = inventoryDetailRepository;
            _putawayOrderRepository = putawayOrderRepository;
            _inventoryRepository = inventoryRepository;
            _lockCellRepository = lockCellRepository;
            _cellRepository = cellRepository;
            _unitOfWork = unitOfWork;
        }
        #region PC
        public bool AddShippingOrderDetail(ShippingOrderDetail m, out string message)
        {
            bool result = false;
            message = string.Empty;
            if (m.SupplierId != null)
            {
                var sobj = _supplierRepository.QueryEntityById((long)m.SupplierId);
                if (sobj != null)
                {
                    m.SupplierName = sobj.Name;
                }
                else
                {
                    message = "供应商不存在或者已被禁用！";
                    return false;
                }
            }
            if (m.CustomerId != null)
            {
                var cobj = _customerRepository.QueryEntityById((long)m.CustomerId);
                if (cobj != null)
                {
                    m.CustomerName = cobj.Name;
                }
                else
                {
                    message = "客户不存在或者已被禁用！";
                    return false;
                }
            }
            if (!string.IsNullOrEmpty(m.AreaCode))
            {
                var aobj = _areaRepository.QueryEntityWhere(x => x.Code == m.AreaCode);
                if (aobj == null || aobj.Status != 1)
                {
                    message = "库区不存在或者已被禁用！";
                    return false;
                }
            }
            m.Status = 0;
            m.ShippedQty = 0;
            m.SourceType = 0;
            //是否挂起-逻辑待处理
            m.IsSuspend = false;
            try
            {
                _unitOfWork.BeginTransaction();
                foreach (var item in m.LockCellList)
                {
                    _shippingOrderDetailRepository.AddEntity(m);
                    _unitOfWork.SaveChangesEntity();
                    if (item.InventoryId == null)
                    {
                        message = "找不到库存信息！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    var invobj = _inventoryRepository.QueryEntityById((long)item.InventoryId);
                    if (invobj == null)
                    {
                        message = "库存信息有误！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    if (invobj.PurOrderLineType == null)
                    {
                        if (item.OutQty != invobj.AvailableQty)
                        {
                            message = "该物资不允许拣选出库！";
                            _unitOfWork.RollbackChanges();
                            return false;
                        }
                        item.IsPicking = false;
                    }
                    else
                        item.IsPicking = true;
                    invobj.PickedQty += item.OutQty;
                    invobj.IsLock = true;
                    if (invobj.AvailableQty == item.OutQty)
                        m.BillType = 1;
                    else
                        m.BillType = 2;
                    m.AreaCode = invobj.AreaCode;
                    m.AreaName = invobj.AreaName;
                    m.WarehouseId = invobj.WarehouseId;
                    m.WarehouseCode = invobj.WarehouseCode;
                    m.WarehouseName = invobj.WarehouseName;
                    m.MaterialId = invobj.MaterialId == null ? 0 : Convert.ToInt64(invobj.MaterialId);
                    m.MaterialName = invobj.MaterialName;
                    m.MaterialCode = invobj.MaterialCode;
                    m.MaterialTypeCode = invobj.MaterialTypeCode;
                    m.UnitId = invobj.UnitId;
                    m.UnitName = invobj.UnitName;
                    m.Qty = item.OutQty;
                    m.BatchNo = invobj.BatchNo;
                    _shippingOrderDetailRepository.UpdEntity(m);
                    item.OrderDetailId = m.Id;
                    item.OrdeSn = m.OrderSn;
                    item.CellId = invobj.LocationId;
                    item.CellCode = invobj.LocationCode;
                    item.CellName = invobj.LocationName;
                    item.CellDepthIndex = invobj.LocationDepth;
                    item.WhId = invobj.WarehouseId;
                    item.PalletBarcode = invobj.PalletBarcode;
                    item.MaterialId = invobj.MaterialId;
                    item.MaterialCode = invobj.MaterialCode;
                    item.MaterialName = invobj.MaterialName;
                    item.MaterialKeyId = invobj.MaterialKeyId;
                    item.RoutewayId = invobj.RoutewayId;
                    item.BatchNo = invobj.BatchNo;
                    item.InventoryQty = invobj.AvailableQty;
                    if (item.OutQty == 0)
                    {
                        message = "出库数量不能为0！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    if (item.OutQty > invobj.AvailableQty)
                    {
                        message = "出库数量不能大于库存可用数量！" + invobj.AvailableQty;
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    if (item.OutQty % 1 != 0)
                    {
                        message = "出库数量不能是小数";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    _lockCellRepository.AddEntity(item);
                    result = _unitOfWork.SaveChangesEntity();
                    if (result == false)
                        break;
                }
                if (result)
                {
                    _unitOfWork.CommitChanges();
                    return true;
                }
                _unitOfWork.RollbackChanges();
                return false;
            }
            catch (Exception)
            {
                _unitOfWork.RollbackChanges();
                throw;
            }

        }

        public bool DelShippingOrderDetail(long id, out string message)
        {
            message = string.Empty;
            var sobj = _shippingOrderDetailRepository.QueryEntityById(id);
            if (sobj != null)
            {
                if (sobj.Status == 3 || sobj.Status == 4)
                {
                    message = "作业中和已完成的单据不可删除！";
                    return false;
                }
                _shippingOrderDetailRepository.DelEntity(sobj);
                var slobjlist = _lockCellRepository.GetEntityWhereAll(x => x.OrderDetailId == sobj.Id).ToList();
                if (slobjlist.Any())
                {
                    foreach (var slobj in slobjlist)
                    {
                        if (slobj.InventoryId == null)
                        {
                            message = "库存信息有误！";
                            return false;
                        }
                        _lockCellRepository.DelEntity(slobj);
                        var iobj = _inventoryRepository.QueryEntityById((long)slobj.InventoryId);
                        if (iobj != null)
                        {
                            iobj.IsLock = false;
                            iobj.PickedQty -= slobj.OutQty;
                            iobj.Status = 1;
                            _inventoryRepository.UpdEntity(iobj);
                            var ilist = _inventoryRepository.GetEntityWhereAll(x => x.PalletBarcode == iobj.PalletBarcode);
                            foreach (var item in ilist)
                            {
                                item.IsLock = false;
                                item.Status = 1;
                                _inventoryRepository.UpdEntity(item);
                            }
                        }
                    }
                }
                return _unitOfWork.SaveChangesEntity();
            }
            message = "找不到出库单！";
            return false;
        }

        public List<ShippingSelectMaterialDto> GetInventoryByMaterialAll(int pageIndex, int pageSize, string? mname, string? arecode, out int count)
        {
            var ilist = _inventoryRepository.GetEntityAlls();
            ilist = ilist.Where(x => x.Status == 1 && x.IsLock == false);

            if (!string.IsNullOrEmpty(arecode))
                ilist = ilist.Where(i => i.AreaCode == arecode);
            if (!string.IsNullOrEmpty(mname))
            {
                ilist = ilist.Where(i => i.MaterialName.Contains(mname) || i.MaterialCode.Contains(mname) || i.LocationName == mname || i.PalletBarcode == mname);
            }
            List<ShippingSelectMaterialDto> shippingSelectMaterialDtos = new List<ShippingSelectMaterialDto>();

            foreach (var item in ilist)
            {
                ShippingSelectMaterialDto dto = new ShippingSelectMaterialDto()
                {
                    InventoryId = item.Id,
                    Code = item.MaterialCode,
                    Name = item.MaterialName,
                    UnitName = item.UnitName,
                    InvCount = item.AvailableQty,
                    PallBarcode = item.PalletBarcode,
                    LocationCode = item.LocationCode,
                    CreatedDate = item.CreateDate,
                    LocationDepth = item.LocationDepth,
                    IsPick = item.PurOrderLineType == null ? false : true,
                    BatchNo = item.BatchNo
                };
                shippingSelectMaterialDtos.Add(dto);
            }
            count = ilist.Count();
            var list = shippingSelectMaterialDtos.OrderByDescending(x => x.CreatedDate).Skip((pageIndex - 1) * pageSize).Take(pageSize);

            return list.ToList();
        }

        public ShippingOrderDetail? GetShippingOrderDetailById(long id)
        {
            var sobj = _shippingOrderDetailRepository.QueryEntityById(id);
            if (sobj == null)
                return null;
            ShippingOrderDetail shippingOrderDetail = new ShippingOrderDetail();
            shippingOrderDetail = sobj;
            var slobjlist = _lockCellRepository.GetEntityWhereAll(x => x.OrderDetailId == sobj.Id);
            if (slobjlist.Any())
                sobj.LockCellList = slobjlist.ToList();
            return shippingOrderDetail;
        }

        public List<ShippingOrderDetail> GetShippingOrderDetailList(string? ordersn,int? billtype, string? materialkey, int status, int pageIndex, int pageSize, out int totalCount)
        {
            var slist = _shippingOrderDetailRepository.GetEntityAlls();
            slist = slist.Where(x => x.BillType == billtype);
            if (!string.IsNullOrEmpty(ordersn))
                slist = slist.Where(x => x.OrderSn.Contains(ordersn));
            if (status < 8)
                slist = slist.Where(x => x.Status == status);

            if (!string.IsNullOrEmpty(materialkey))
                slist = slist.Where(x => x.MaterialCode.Contains(materialkey) || x.MaterialName.Contains(materialkey));

            var list = _shippingOrderDetailRepository.GetEntityAlls(slist, pageIndex, pageSize, out totalCount, x => x.CreateDate, false);
            return list.ToList();
        }

        public bool UpdShippingOrderDetail(ShippingOrderDetail m, out string message)
        {
            message = string.Empty;
            bool result = false;
            if (m.Status == 3 || m.Status == 4)
            {
                message = "作业中和已完成的单据不可修改！";
                return false;
            }
            if (m.SupplierId != null)
            {
                var sobj = _supplierRepository.QueryEntityById((long)m.SupplierId);
                if (sobj != null)
                {
                    m.SupplierName = sobj.Name;
                }
                else
                {
                    message = "供应商不存在或者已被禁用！";
                    return false;
                }
            }
            if (m.CustomerId != null)
            {
                var cobj = _customerRepository.QueryEntityById((long)m.CustomerId);
                if (cobj != null)
                {
                    m.CustomerName = cobj.Name;
                }
                else
                {
                    message = "客户不存在或者已被禁用！";
                    return false;
                }
            }
            if (!string.IsNullOrEmpty(m.AreaCode))
            {
                var aobj = _areaRepository.QueryEntityWhere(x => x.Code == m.AreaCode);
                if (aobj == null || aobj.Status != 1)
                {
                    message = "库区不存在或者已被禁用！";
                    return false;
                }
            }
            m.Status = 0;
            m.ShippedQty = 0;
            m.SourceType = 0;
            //是否挂起-逻辑待处理
            m.IsSuspend = false;
            m.Qty = 0;
            try
            {
                _unitOfWork.BeginTransaction();
                var slobjlist = _lockCellRepository.GetEntityWhereAll(x => x.OrderDetailId == m.Id).ToList();
                if (slobjlist.Any())
                {
                    foreach (var slobj in slobjlist)
                    {
                        _lockCellRepository.DelEntity(slobj);
                        if (slobj.InventoryId == null)
                        {
                            message = "库存信息有误！";
                            _unitOfWork.RollbackChanges();
                            return false;
                        }
                        var uinvobj = _inventoryRepository.QueryEntityById((long)slobj.InventoryId);
                        if (uinvobj != null)
                        {
                            uinvobj.IsLock = false;
                            uinvobj.Status = 1;
                            uinvobj.PickedQty -= slobj.OutQty;
                        }
                    }

                }
                foreach (var item in m.LockCellList)
                {
                    if (item.InventoryId == null)
                    {
                        message = "找不到库存信息！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    var invobj = _inventoryRepository.QueryEntityById((long)item.InventoryId);
                    if (invobj == null)
                    {
                        message = "库存信息有误！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    if (invobj.PurOrderLineType == null)
                    {
                        if (item.OutQty != invobj.AvailableQty)
                        {
                            message = "该物资不允许拣选出库！";
                            _unitOfWork.RollbackChanges();
                            return false;
                        }
                        item.IsPicking = false;
                    }
                    else
                        item.IsPicking = true;
                    if (invobj.AvailableQty == item.OutQty)
                        m.BillType = 1;
                    else
                        m.BillType = 2;
                    invobj.IsLock = true;
                    invobj.PickedQty += item.OutQty;
                    m.AreaCode = invobj.AreaCode;
                    m.AreaName = invobj.AreaName;
                    m.WarehouseId = invobj.WarehouseId;
                    m.WarehouseCode = invobj.WarehouseCode;
                    m.WarehouseName = invobj.WarehouseName;
                    m.MaterialId = invobj.MaterialId == null ? 0 : Convert.ToInt64(item.MaterialId);
                    m.MaterialName = invobj.MaterialName;
                    m.MaterialCode = invobj.MaterialCode;
                    m.MaterialTypeCode = invobj.MaterialTypeCode;
                    m.UnitId = invobj.UnitId;
                    m.UnitName = invobj.UnitName;
                    m.Qty = item.OutQty;
                    m.BatchNo = invobj.BatchNo;
                    _shippingOrderDetailRepository.UpdEntity(m);
                    item.OrderDetailId = m.Id;
                    item.OrdeSn = m.OrderSn;
                    item.CellId = invobj.LocationId;
                    item.CellCode = invobj.LocationCode;
                    item.CellName = invobj.LocationName;
                    item.CellDepthIndex = invobj.LocationDepth;
                    item.WhId = invobj.WarehouseId;
                    item.PalletBarcode = invobj.PalletBarcode;
                    item.MaterialId = invobj.MaterialId;
                    item.MaterialCode = invobj.MaterialCode;
                    item.MaterialName = invobj.MaterialName;
                    item.MaterialKeyId = invobj.MaterialKeyId;
                    item.RoutewayId = invobj.RoutewayId;
                    item.BatchNo = invobj.BatchNo;
                    item.InventoryQty = invobj.AvailableQty;
                    if (item.OutQty == 0)
                    {
                        message = "出库数量不能为0！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    if (item.OutQty > invobj.AvailableQty)
                    {
                        message = "出库数量不能大于库存可用数量！" + invobj.AvailableQty;
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    if (item.OutQty % 1 != 0)
                    {
                        message = "出库数量不能是小数";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    _lockCellRepository.AddEntity(item);
                    result = _unitOfWork.SaveChangesEntity();
                    if (result == false)
                        break;
                }
                if (result)
                {
                    _unitOfWork.CommitChanges();
                    return true;
                }
                _unitOfWork.RollbackChanges();
                return false;
            }
            catch (Exception)
            {
                _unitOfWork.RollbackChanges();
                throw;
            }
        }
        #endregion

        #region PDA
        public List<ShippingOrderDetailGroupDTO> GetShippingOrderDetailGroup(string key, int pageIndex, int pageSize, out int totalCount)
        {
            var shippingOrderDetails = _shippingOrderDetailRepository.GetEntityAlls()
                .Where(s => s.Status < 4 && s.IsSuspend == false);

            if (!string.IsNullOrEmpty(key))
            {
                shippingOrderDetails = shippingOrderDetails.Where(x => x.MaterialCode.Contains(key));
            }
            var lockCellslist = _lockCellRepository.GetEntityAlls().Where(x => x.Status == 0);
            //var shippingOrderDetailLookup = shippingOrderDetails.ToLookup(s => s.OrderSn);

            //var lockCells = _lockCellRepository.GetEntityAlls().ToDictionary(lc => lc.OrderDetailId);

            //List<ShippingOrderDetailGroupDTO> resList = new List<ShippingOrderDetailGroupDTO>();
            //foreach (var group in shippingOrderDetailLookup)
            //{
            //    var shippingOrderDetailGroupDTO = new ShippingOrderDetailGroupDTO
            //    {
            //        OrderSn = group.Key,
            //        CheckedAll = false,
            //        LockCells = new List<ShippingLockCell>()
            //    };

            //    foreach (var detail in group)
            //    {
            //        if (lockCells.TryGetValue(detail.Id, out var lockCell))
            //        {
            //            shippingOrderDetailGroupDTO.LockCells.Add(lockCell);
            //        }
            //    }

            //    resList.Add(shippingOrderDetailGroupDTO);
            //}
            var shippingOrderDetailLookup = shippingOrderDetails.ToList().GroupBy(s => s.OrderSn);
            List<ShippingOrderDetailGroupDTO> resList = new List<ShippingOrderDetailGroupDTO>();
            foreach (var item in shippingOrderDetailLookup)
            {
                ShippingOrderDetailGroupDTO? shippingOrderDetailGroupDTO = new ShippingOrderDetailGroupDTO();
                shippingOrderDetailGroupDTO.OrderSn = item.Key;
                shippingOrderDetailGroupDTO.CheckedAll = false;
                shippingOrderDetailGroupDTO.LockCells = new List<ShippingLockCell>();
                var lockCells = lockCellslist.Where(x => x.OrdeSn == item.Key);
                shippingOrderDetailGroupDTO.LockCells = lockCells.ToList();
                if (!lockCells.Any())
                    continue;
                resList.Add(shippingOrderDetailGroupDTO);
            }
            totalCount = resList.Count;
            resList = resList.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();

            return resList;
        }
        #region 原来的
        public bool StartShippingOrderDetail(List<SubmitOutListDTO> m, out string message)
        {
            message = string.Empty;
            try
            {
                bool result = false;
                List<Cell> outcell = new List<Cell>(); //出库的仓位
                List<Tasks> tasks = new List<Tasks>(); //待执行的指令

                _unitOfWork.BeginTransaction();
                //查看站台模式，必须为出库才可以 A01为固定值
                var stationobj = _stationRepository.QueryEntityWhere(s => s.Code == "A01");
                if (stationobj is null)
                {
                    message = "未查询到入库口信息！";
                    return false;
                }
                if (stationobj.FunctionType != 2)
                {
                    message = "当前模式不是出库!";
                    return false;
                }
                //var putawayOrderObj = _putawayOrderRepository.QueryEntityWhere(s => s.Status == 4 && s.SourceType == 1);
                //if (putawayOrderObj != null)
                //{
                //    message = "当前有入库任务还有执行完！";
                //    return false;
                //}

                //验证出库数据以及创建下架单和修改库存数据，获取所有出库的仓位
                foreach (var item in m)
                {
                    int? billtype;
                    //物料id
                    long materid = 0;
                    var lockobj = _lockCellRepository.QueryEntityById(item.OrderDetId);
                    if (lockobj == null)
                    {
                        message = "未查询到出库单详情";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    // 出库单数量修改 状态修改
                    if (lockobj.OrderDetailId == null)
                    {
                        message = "出库单信息有误！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    if (lockobj.Status == 3)
                    {
                        message = "当前任务正在作业中！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    if (lockobj.Status == 4)
                    {
                        message = "当前任务已完成！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    lockobj.Status = 3;
                    var shippingOrderDetail = _shippingOrderDetailRepository.QueryEntityById((long)lockobj.OrderDetailId);
                    if (shippingOrderDetail == null)
                    {
                        message = "获取出库单信息失败";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    if (shippingOrderDetail.Status == 4)
                    {
                        message = "当前出库单已完成";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    billtype = shippingOrderDetail.BillType;
                    shippingOrderDetail.Status = 3;
                    materid = lockobj.MaterialId == null ? 0 : Convert.ToInt64(lockobj.MaterialId);
                    var cellobj = _cellRepository.QueryEntityWhere(x => x.Code == lockobj.CellCode);
                    if (cellobj == null)
                    {
                        message = "未查询到仓位" + lockobj.CellCode;
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    if (cellobj.Status != 1)
                    {
                        message = "当前仓位已被禁用！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    if (cellobj.RoutewayId == null)
                    {
                        message = "找不到该仓位所属的巷道！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    long? invid = lockobj.InventoryId;
                    if (invid == null)
                    {
                        message = "获取库存id有误！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    Inventory? inventoryModel = _inventoryRepository.QueryEntityById((long)invid);
                    //状态修改出库在途         
                    if (inventoryModel == null)
                    {
                        message = "获取库存信息失败！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    if (inventoryModel.AvailableQty < item.Qty)
                    {
                        message = "库存数量不足！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    inventoryModel.Status = 4;
                    var inventorylist = _inventoryRepository.GetEntityWhereAll(x => x.PalletBarcode == item.PalletBarcode && x.Status == 1);
                    if (inventorylist.Any())
                    {
                        foreach (var item2 in inventorylist)
                        {
                            item2.IsLock = true;
                            item2.Status = 4;
                            _inventoryRepository.UpdEntity(item2);
                        }
                    }
                    #region 添加指令
                    Instruct inobj = new Instruct();
                    inobj.WarehouseCode = inventoryModel.WarehouseCode;
                    inobj.Status = 2;
                    inobj.FromLocation = item.StationCode;
                    inobj.ToLocation = inventoryModel.LocationCode;
                    inobj.WorkDeviceType = 1;
                    if (billtype == 2)
                        inobj.InstructType = 6;
                    else
                        inobj.InstructType = 2;
                    inobj.Action = 0;
                    inobj.RelatedOrderId = shippingOrderDetail.Id;
                    inobj.ExpectedToLocation = inventoryModel.LocationCode;
                    inobj.InstructIndex = 1;
                    inobj.PalletBarcode = item.PalletBarcode;
                    inobj.ScanedBarcode = item.PalletBarcode;
                    inobj.Priority = 9999;
                    inobj.Qty = item.Qty;
                    inobj.FinishedQty = 0;
                    inobj.BusinessType = (int)EmBusinessType.Out;
                    inobj.RelatedOrderDetailId = lockobj.Id;
                    _instructRepository.AddEntity(inobj);
                    #endregion
                    #region 添加下架单
                    string str = DateTime.Now.ToString("yyyyMMddHHmmssfff");
                    string pickCode = "OUT" + str;
                    PickingOrder pickOrder = new PickingOrder();
                    pickOrder.Id = YitIdHelper.NextId();
                    pickOrder.Code = pickCode;
                    pickOrder.WarehouseCode = inventoryModel.WarehouseCode;
                    pickOrder.WarehouseName = inventoryModel.WarehouseName;
                    if (billtype == 2)
                        pickOrder.BillType = 2;
                    else
                        pickOrder.BillType = 1;
                    pickOrder.DescAddress = item.DescAddress;
                    pickOrder.PalletBarcode = item.PalletBarcode;
                    pickOrder.Roadway = cellobj.RoutewayId.ToString();
                    pickOrder.LocationCode = cellobj.Code;
                    pickOrder.LocationDepth = cellobj.DepthIndex;
                    pickOrder.Status = 4;
                    pickOrder.Qty = item.Qty;
                    pickOrder.MaterialId = materid;
                    pickOrder.MaterialCode = lockobj.MaterialCode;
                    pickOrder.MaterialName = lockobj.MaterialName;
                    pickOrder.MaterialKeyId = inventoryModel.MaterialKeyId;
                    pickOrder.BatchNo = inventoryModel.BatchNo;
                    pickOrder.SourceType = 2;
                    pickOrder.RelatedOrderDetailId = item.OrderDetId;
                    pickOrder.CreateDate = DateTime.Now;
                    _pickingOrderRepository.AddEntity(pickOrder);
                    PickingOrderDetail pickOrderDetail = new PickingOrderDetail();
                    pickOrderDetail.Id = YitIdHelper.NextId();
                    pickOrderDetail.OrderId = pickOrder.Id;
                    pickOrderDetail.PalletBarcode = item.PalletBarcode;
                    pickOrderDetail.MaterialBarcode = lockobj.MaterialCode;
                    _pickingOrderDetailRepository.AddEntity(pickOrderDetail);
                    #endregion
                    result = _unitOfWork.SaveChangesEntity();
                    if (!result)
                    {
                        message = "出库失败!";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    if (outcell.Any(c=>c.Code == cellobj.Code))
                    {
                        continue;
                    }
                    outcell.Add(cellobj); //将出库仓位都存起来
                }

                //对出库的仓位进行排序 根据深位进行排序 低深位在前面
                outcell = outcell.OrderBy(c=> c.DepthIndex).ToList();
                int order = 1; //任务顺序
                foreach (var item in outcell)
                {
                    var data = m.FirstOrDefault(m=>m.LocationCode == item.Code);
                    if (data is null)
                    {
                        message = "获取仓位失败!";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    if (item.DepthIndex == 1)
                    {
                        var picking = _pickingOrderRepository.QueryEntityWhere(p => p.Status == 4 && p.PalletBarcode == data.PalletBarcode && p.SourceType == 2);
                        if (picking == null)
                        {
                            message = "获取上架单失败";
                            _unitOfWork.RollbackChanges();
                            return false;
                        }
                        picking.DescAddress = "A01"; //把下架单任务终点改成A01,下架单任务终点为A01的则为给WCS下发的任务
                        _pickingOrderRepository.UpdEntity(picking);

                        //等于1时不用移库直接生成任务
                        tasks.Add(new Tasks()
                        {
                            TaskId = picking.Code,
                            TaskType = 1,
                            BarCode = picking.PalletBarcode,
                            EndNode = "A01",
                            StartNode = picking.LocationCode,
                            Order = order
                        });
                        order++;
                    }
                    else
                    {
                        //使用三元表达式，来判断查询条件
                        var depthCell = item.LineNo > 4 ? _cellRepository.GetEntityWhereAll(c => c.LayerNo == item.LayerNo && c.ColumnNo == item.ColumnNo && c.LineNo < item.LineNo && c.LineNo > 4).OrderBy(c => c.DepthIndex).ToList() : _cellRepository.GetEntityWhereAll(c => c.LayerNo == item.LayerNo && c.ColumnNo == item.ColumnNo && c.LineNo > item.LineNo && c.LineNo < 4).OrderBy(c => c.DepthIndex).ToList();

                        if (depthCell.Count() <= 0)
                        {
                            message = "获取出库仓位深位的其他仓位失败！";
                            _unitOfWork.RollbackChanges();
                            return false;
                        }
                        foreach (var decell in depthCell) //循环查看仓位是否需要进行移库
                        {
                            var inventory = _inventoryRepository.QueryEntityWhere(i => i.LocationCode == decell.Code);
                            if (inventory is null)
                            {
                                continue; //如果仓位没有在库存中查询出数据代表仓位上没有物料可以直接下一个
                            }
                            if (inventory.Status == 4 || inventory.Status == 2)
                            {
                                continue; //如果库存数据等于移库和出库就代表已经下任务了不用再下任务了
                            }
                            if (inventory.Status == 1) //如果是正常库存需要进行移库
                            {
                                //传入的是需要移库的仓位数据而不是出库仓位数据
                                var transCellData = ShippingTransferBinInventory(decell.LayerNo, decell.Code, decell.AreaCode, out message);  
                                if (transCellData == null)
                                {
                                    message = "创建移库任务失败，" + message;
                                    _unitOfWork.RollbackChanges();
                                    return false;
                                }
                                //查询移库单
                                var putaway = _putawayOrderRepository.QueryEntityWhere(p => p.Status == 4 && p.LocationCode == transCellData.Code && p.SourceType == 3);
                                if (putaway == null)
                                {
                                    message = "未查询到移库任务!";
                                    _unitOfWork.RollbackChanges();
                                    return false;
                                }
                                //添加移库任务
                                tasks.Add(new Tasks()
                                {
                                    TaskId = putaway.Code,
                                    TaskType = 2,
                                    BarCode = putaway.PalletBarcode,
                                    EndNode = putaway.LocationCode,
                                    StartNode = decell.Code,
                                    Order = order
                                });
                                order++;
                            }
                        }

                        //遍历完出库仓位的其他深位仓位之后需要出库仓位添加出库任务
                        var picking = _pickingOrderRepository.QueryEntityWhere(p => p.Status == 4 && p.PalletBarcode == data.PalletBarcode && p.SourceType == 2);
                        if (picking == null)
                        {
                            message = "获取上架单失败";
                            _unitOfWork.RollbackChanges();
                            return false;
                        }
                        picking.DescAddress = "A01"; //把下架单任务终点改成A01,下架单任务终点为A01的则为给WCS下发的任务
                        _pickingOrderRepository.UpdEntity(picking);

                        //生成出库任务
                        tasks.Add(new Tasks()
                        {
                            TaskId = picking.Code,
                            TaskType = 1,
                            BarCode = picking.PalletBarcode,
                            EndNode = "A01",
                            StartNode = picking.LocationCode,
                            Order = order
                        });
                        order++;
                    }

                    result = _unitOfWork.SaveChangesEntity();
                    if (!result)
                    {
                        message = "出库下架单站台修改失败!";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                }

                if (result)
                {
                    #region 下发任务
                    if (Config.IsDev == false)
                    {
                        TaskAccept taskAccept = new TaskAccept
                        {
                            tasks = tasks,
                            Warehouse = Config.WMSWarehouseCode,
                            GroupId = Guid.NewGuid().ToString("N"),
                            MsgTime = DateTime.Now.ToString(),
                            PriorityCode = 20 //优先级20
                        };

                        var newWcsApi = wcsHttp.TaskAcceptApi(taskAccept);
                        if (newWcsApi.returnStatus != 0)
                        {
                            message = newWcsApi.returnInfo;
                            _unitOfWork.RollbackChanges();
                            return false;
                        }
                    }
                    message = "操作成功！";
                    _unitOfWork.CommitChanges();
                    return true;
                    #endregion
                }
                _unitOfWork.RollbackChanges();
                return false;
            }
            catch (Exception)
            {
                _unitOfWork.RollbackChanges();
                throw;
            }

        }
        
        #endregion

        #region 出库产生移库逻辑处理
        private Cell? ShippingTransferBinInventory(int layerno, string trancellcode, string acode, out string message)
        {
            message = string.Empty;
            #region 修改库存状态
            var toCell = GetCellCode(acode, layerno, out message);
            if (toCell == null)
            {
                message = "当前层没有可移库的仓位了！";
                return null;
            }
            else
            {
                toCell.FullStatus = 1;
                toCell.IsLock = true;
                toCell.BusinessType = 1;
                toCell.ModifyDate = DateTime.Now;
                _cellRepository.UpdEntity(toCell);
            }
            bool isshipplost = false;
            var slocklist = _lockCellRepository.GetEntityWhereAll(x => x.CellCode == trancellcode && x.Status == 0).ToList();
            foreach (var item2 in slocklist)
            {
                //标记状态列
                item2.CellId = toCell.Id;
                item2.CellCode = toCell.Code;
                item2.CellName = toCell.Name;
                item2.Status = 3;
                isshipplost = true;
                _lockCellRepository.UpdEntity(item2);
            }
            var tinventorylist = _inventoryRepository.GetEntityWhereAll(it => it.LocationCode == trancellcode).ToList();
            foreach (var inventory in tinventorylist)
            {
                inventory.LocationId = toCell.Id;
                inventory.LocationName = toCell.Name;
                inventory.LocationCode = toCell.Code;
                inventory.LocationDepth = toCell.DepthIndex;
                inventory.LocationLineNo = toCell.LineNo;
                inventory.LocationLayerNo = toCell.LayerNo;
                inventory.LocationColumnNo = toCell.ColumnNo;
                inventory.Status = 2;
                inventory.LocationHeightType = toCell.HeightType;
                inventory.IsLock = true;
                inventory.RoutewayId = toCell.RoutewayId;
                inventory.ErplocationCode = toCell.Erpcode;
                if (isshipplost)
                    inventory.Remark = "系统移库";
                _inventoryRepository.UpdEntity(inventory);
                #region 关联的入库单做处理
                if (inventory.RelatedOrderDetailId == null)
                {
                    message = "关联的入库单id有误！";
                    return null;
                }
                var revingobj = _receivingOrderDetailRepository.QueryEntityById((long)inventory.RelatedOrderDetailId);
                if (revingobj == null)
                {
                    message = "入库单明细不存在或已被删除";
                    return null;
                }
                #region 指令管理
                Instruct instruct = null;
                instruct = new Instruct
                {
                    Id = YitIdHelper.NextId(),
                    WarehouseCode = toCell.WhCode,
                    Status = 2,
                    FromLocation = trancellcode,
                    ToLocation = toCell.Code,
                    StackingStorageId = 0,
                    WorkDeviceType = 1,
                    InstructType = 3,
                    Action = 0,
                    RelatedOrderId = revingobj.Id,
                    RelatedOrderDetailId = 0,
                    DeviceCode = "",
                    ExpectedToLocation = toCell.Code,
                    InstructIndex = 1,
                    PalletBarcode = inventory.PalletBarcode,
                    ScanedBarcode = inventory.PalletBarcode,
                    Priority = 9999,
                    Qty = inventory.AvailableQty == null ? 0 : (decimal)inventory.AvailableQty,
                    FinishedQty = 0,
                    CreateDate = DateTime.Now,
                    BusinessType = (int)EmBusinessType.Move,
                    BillType = (int)revingobj.BillType.GetValueOrDefault(),
                };
                _instructRepository.AddEntity(instruct);
                #endregion
                #endregion


                #endregion
                #region 上架单
                string tstr = DateTime.Now.ToString("yyyyMMddHHmmssfff");
                string traawayCode = "TRA" + tstr;
                PutawayOrder putawayOrder = new PutawayOrder();
                putawayOrder.Id = YitIdHelper.NextId();
                putawayOrder.Code = traawayCode;
                putawayOrder.RelatedOrderDetailId = tinventorylist.First().RelatedOrderDetailId;
                putawayOrder.StackingStorageId = 0;
                putawayOrder.PalletBarcode = tinventorylist.First().PalletBarcode;
                putawayOrder.LocationCode = toCell.Code;
                putawayOrder.LocationDepth = toCell.DepthIndex == 0 ? null : toCell.DepthIndex;
                putawayOrder.Status = 4;
                putawayOrder.Qty = tinventorylist.First().AvailableQty;
                putawayOrder.CreateDate = DateTime.Now;
                putawayOrder.MaterialId = tinventorylist.First().MaterialId;
                putawayOrder.MaterialCode = tinventorylist.First().MaterialCode;
                putawayOrder.MaterialName = tinventorylist.First().MaterialName;
                putawayOrder.MaterialKeyId = tinventorylist.First().MaterialKeyId;
                putawayOrder.BatchNo = tinventorylist.First().BatchNo;
                putawayOrder.CreateUserId = 0;
                putawayOrder.CreateUserName = "系统";
                putawayOrder.SourceType = 3;
                putawayOrder.SiteCode = "";
                _putawayOrderRepository.AddEntity(putawayOrder);
            }
            var pallobj = _palletRepository.QueryEntityWhere(x => x.LocationCode == trancellcode);
            if (pallobj != null)
            {
                pallobj.LocationName = toCell.Name;
                pallobj.LocationCode = toCell.Code;
            }

            #endregion
            if (!_unitOfWork.SaveChangesEntity())
            {
                message = "修改数据失败";
                return null;
            }
            
            return toCell;
        }

        private Cell? GetCellCode(string acode, int layerno, out string message)
        {
            message = string.Empty;
            if (string.IsNullOrEmpty(acode))
            {
                message = "库区编码有误！";
                return null;
            }
            Cell? cellobj = new Cell();
            //获取所有库区
            var areaobj = _areaRepository.QueryIsEntityWhere(x => x.Code == acode && x.Status == 1);
            if (areaobj == null || areaobj.WhId == null)
            {
                message = "库区不存在或已被禁用!";
                return null;
            }
            long? wid = areaobj.WhId;
            //获取所有库房
            var warehouseobj = _warehouseRepository.QueryIsEntityWhere(x => x.Id == wid && x.Status == 1);
            if (warehouseobj == null)
            {
                message = "库房不存在或已被禁用!";
                return null;
            }

            //获取所有巷道
            var routewayQuery = _routewayRepository.GetEntityWhereAll(x => x.WhId == wid && x.Status == 1);
            if (routewayQuery == null)
            {
                message = "无可用巷道!";
                return null;
            }
            List<long> enabledRoutewayIds = routewayQuery.Select(t => t.Id).ToList();//只取巷道id
            // 获取所有货架
            var shelves = _shelfRepository.GetEntityWhereAll(x => x.WhId == wid && x.AreaId == areaobj.Id && x.Status == 1 && enabledRoutewayIds.Contains((long)x.RoutewayId));
            if (shelves == null)
            {
                message = "无可用货架!";
                return null;
            }
            List<long> enabledShelves = shelves.Select(t => t.Id).ToList();//只取货架id
            //获取所有可用仓位
            var cellQuery = _cellRepository
                .GetEntityWhereAll(x => x.AreaCode == acode
                                        && x.Status == 1
                                        && x.FullStatus == 0
                                        && x.IsLock == false
                                        && x.LayerNo == layerno
                                        && enabledRoutewayIds.Contains((long)x.RoutewayId)
                                        && enabledShelves.Contains((long)x.ShelfId)).ToList();
            if (!cellQuery.Any())
            {
                message = "无可用仓位!";
                return null;
            }
            //var inventoryQuery = Context.TInventory.AsNoTracking(); //获取库存数据
            cellobj = cellQuery.Where(x => x.IsMaxDepth == true).OrderByDescending(c => c.DepthIndex)
                                .ThenBy(c => c.LayerNo)
                                .ThenBy(c => c.ColumnNo)
                                .ThenBy(c => c.LineNo)
                                .FirstOrDefault();
            if (cellobj != null)
            {
                return cellobj;
            }
            else
            {
                cellobj = cellQuery.Where(x => x.IsMaxDepth == false).OrderByDescending(c => c.DepthIndex)
                              .ThenBy(c => c.LayerNo)
                              .ThenBy(c => c.ColumnNo)
                              .ThenBy(c => c.LineNo)
                              .FirstOrDefault();
                if (cellobj != null)
                {
                    return cellobj;
                }
            }
            if (cellobj == null)
                message = "无可用仓位!";
            return null;
        }
        #endregion

        #region 最新的出库 弃用自动移库
        /*
        public bool StartShippingOrderDetail(List<SubmitOutListDTO> m, out string message)
        {
            message = string.Empty;
            try
            {
                bool result = false;
                foreach (var item in m)
                {
                    _unitOfWork.BeginTransaction();
                    //物料id
                    long materid = 0;
                    //托盘条码
                    string pacode = item.PalletBarcode;
                    int? billtype;
                    var lockobj = _lockCellRepository.QueryEntityById(item.OrderDetId);
                    if (lockobj == null)
                    {
                        message = "未查询到出库单详情";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    // 出库单数量修改 状态修改
                    if (lockobj.OrderDetailId == null)
                    {
                        message = "出库单信息有误！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    if (lockobj.Status == 3)
                    {
                        message = "当前任务正在作业中！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    if (lockobj.Status == 4)
                    {
                        message = "当前任务已完成！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    lockobj.Status = 3;
                    var shippingOrderDetail = _shippingOrderDetailRepository.QueryEntityById((long)lockobj.OrderDetailId);
                    if (shippingOrderDetail == null)
                    {
                        message = "获取出库单信息失败";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    if (shippingOrderDetail.Status == 4)
                    {
                        message = "当前出库单已完成";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    billtype = shippingOrderDetail.BillType;
                    shippingOrderDetail.Status = 3;
                    materid = lockobj.MaterialId == null ? 0 : Convert.ToInt64(lockobj.MaterialId);
                    var cellobj = _cellRepository.QueryEntityWhere(x => x.Code == lockobj.CellCode);
                    if (cellobj == null)
                    {
                        message = "未查询到仓位" + lockobj.CellCode;
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    if (cellobj.Status != 1)
                    {
                        message = "当前仓位已被禁用！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    if (cellobj.RoutewayId == null)
                    {
                        message = "找不到该仓位所属的巷道！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    long? invid = lockobj.InventoryId;
                    if (invid == null)
                    {
                        message = "获取库存id有误！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    Inventory? inventoryModel = _inventoryRepository.QueryEntityById((long)invid);
                    //状态修改出库在途         
                    if (inventoryModel == null)
                    {
                        message = "获取库存信息失败！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    #region 如果浅深位有货物提示
                    //排
                    string rows = inventoryModel.LocationCode.Substring(0, 2);
                    //列
                    string columns = inventoryModel.LocationCode.Substring(2, 2);
                    if (string.IsNullOrEmpty(rows))
                    {
                        message = "获取仓位排失败！";
                        return false;
                    }
                    if (string.IsNullOrEmpty(columns))
                    {
                        message = "获取仓位列失败！";
                        return false;
                    }
                    int row = Convert.ToInt32(rows);
                    int col = Convert.ToInt32(columns);
                    //双深位：1列所有，16排5列，20排5列，21排5列，22排5列，8列所有
                    //三深位：22排6列，23排9列，24排9列，25排9列                 
                    if (col == 1)
                    {
                        string modifiedcellcode = inventoryModel.LocationCode.Substring(0, 2) + "02" + inventoryModel.LocationCode.Substring(4);
                        var inventorycell = _inventoryRepository.QueryEntityWhere(x => x.LocationCode == modifiedcellcode);
                        if (inventorycell != null)
                        {
                            message = inventorycell.LocationName + "仓位已被占用！";
                            _unitOfWork.RollbackChanges();
                            return false;
                        }
                    }
                    else if (col == 6)
                    {
                        string modifiedcellcode = inventoryModel.LocationCode.Substring(0, 2) + "04" + inventoryModel.LocationCode.Substring(4);
                        var inventorycell = _inventoryRepository.QueryEntityWhere(x => x.LocationCode == modifiedcellcode);
                        if (inventorycell != null)
                        {
                            message = inventorycell.LocationName + "仓位已被占用！";
                            _unitOfWork.RollbackChanges();
                            return false;
                        }
                        modifiedcellcode = inventoryModel.LocationCode.Substring(0, 2) + "05" + inventoryModel.LocationCode.Substring(4);
                        var inventorycellcode2 = _inventoryRepository.QueryEntityWhere(x => x.LocationCode == modifiedcellcode);
                        if (inventorycellcode2 != null)
                        {
                            message = inventorycellcode2.LocationName + "仓位已被占用！";
                            _unitOfWork.RollbackChanges();
                            return false;
                        }
                    }
                    else if (col == 8)
                    {
                        string modifiedcellcode = inventoryModel.LocationCode.Substring(0, 2) + "07" + inventoryModel.LocationCode.Substring(4);
                        var inventorycell = _inventoryRepository.QueryEntityWhere(x => x.LocationCode == modifiedcellcode);
                        if (inventorycell != null)
                        {
                            message = inventorycell.LocationName + "仓位已被占用！";
                            _unitOfWork.RollbackChanges();
                            return false;
                        }
                    }
                    else if (col == 9)
                    {
                        string modifiedcellcode = inventoryModel.LocationCode.Substring(0, 2) + "07" + inventoryModel.LocationCode.Substring(4);
                        var inventorycell = _inventoryRepository.QueryEntityWhere(x => x.LocationCode == modifiedcellcode);
                        if (inventorycell != null)
                        {
                            message = inventorycell.LocationName + "仓位已被占用！";
                            _unitOfWork.RollbackChanges();
                            return false;
                        }
                        modifiedcellcode = inventoryModel.LocationCode.Substring(0, 2) + "08" + inventoryModel.LocationCode.Substring(4);
                        var inventorycell2 = _inventoryRepository.QueryEntityWhere(x => x.LocationCode == modifiedcellcode);
                        if (inventorycell2 != null)
                        {
                            message = inventorycell2.LocationName + "仓位已被占用！";
                            _unitOfWork.RollbackChanges();
                            return false;
                        }
                    }
                    else if (col == 5 && (row == 16 || row == 20 || row == 21 || row == 22))
                    {
                        string modifiedcellcode = inventoryModel.LocationCode.Substring(0, 2) + "04" + inventoryModel.LocationCode.Substring(4);
                        var inventorycell = _inventoryRepository.QueryEntityWhere(x => x.LocationCode == modifiedcellcode);
                        if (inventorycell != null)
                        {
                            message = inventorycell.LocationName + "仓位已被占用！";
                            _unitOfWork.RollbackChanges();
                            return false;
                        }
                    }
                    #endregion
                    if (inventoryModel.AvailableQty < item.Qty)
                    {
                        message = "库存数量不足！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    inventoryModel.Status = 4;
                    var inventorylist = _inventoryRepository.GetEntityWhereAll(x => x.PalletBarcode == pacode && x.Status == 1);
                    if (inventorylist.Any())
                    {
                        foreach (var item2 in inventorylist)
                        {
                            item2.IsLock = true;
                            item2.Status = 4;
                            _inventoryRepository.UpdEntity(item2);
                        }
                    }
                    #region 添加指令
                    Instruct inobj = new Instruct();
                    inobj.WarehouseCode = inventoryModel.WarehouseCode;
                    inobj.Status = 2;
                    inobj.FromLocation = item.StationCode;
                    inobj.ToLocation = inventoryModel.LocationCode;
                    inobj.WorkDeviceType = 1;
                    if (billtype == 2)
                        inobj.InstructType = 6;
                    else
                        inobj.InstructType = 2;
                    inobj.Action = 0;
                    inobj.RelatedOrderId = shippingOrderDetail.Id;
                    inobj.ExpectedToLocation = inventoryModel.LocationCode;
                    inobj.InstructIndex = 1;
                    inobj.PalletBarcode = pacode;
                    inobj.ScanedBarcode = pacode;
                    inobj.Priority = 9999;
                    inobj.Qty = item.Qty;
                    inobj.FinishedQty = 0;
                    inobj.BusinessType = (int)EmBusinessType.Out;
                    inobj.RelatedOrderDetailId = lockobj.Id;
                    _instructRepository.AddEntity(inobj);
                    #endregion
                    #region 添加下架单
                    string str = DateTime.Now.ToString("yyyyMMddHHmmssfff");
                    string pickCode = "OUT" + str;
                    PickingOrder pickOrder = new PickingOrder();
                    pickOrder.Id = YitIdHelper.NextId();
                    pickOrder.Code = pickCode;
                    pickOrder.WarehouseCode = inventoryModel.WarehouseCode;
                    pickOrder.WarehouseName = inventoryModel.WarehouseName;
                    if (billtype == 2)
                        pickOrder.BillType = 2;
                    else
                        pickOrder.BillType = 1;
                    pickOrder.DescAddress = item.DescAddress;
                    pickOrder.PalletBarcode = pacode;
                    pickOrder.Roadway = cellobj.RoutewayId.ToString();
                    pickOrder.LocationCode = cellobj.Code;
                    pickOrder.LocationDepth = cellobj.DepthIndex;
                    pickOrder.Status = 4;
                    pickOrder.Qty = item.Qty;
                    pickOrder.MaterialId = materid;
                    pickOrder.MaterialCode = lockobj.MaterialCode;
                    pickOrder.MaterialName = lockobj.MaterialName;
                    pickOrder.MaterialKeyId = inventoryModel.MaterialKeyId;
                    pickOrder.BatchNo = inventoryModel.BatchNo;
                    pickOrder.SourceType = 2;
                    pickOrder.RelatedOrderDetailId = item.OrderDetId;
                    pickOrder.CreateDate = DateTime.Now;
                    _pickingOrderRepository.AddEntity(pickOrder);
                    PickingOrderDetail pickOrderDetail = new PickingOrderDetail();
                    pickOrderDetail.Id = YitIdHelper.NextId();
                    pickOrderDetail.OrderId = pickOrder.Id;
                    pickOrderDetail.PalletBarcode = pacode;
                    pickOrderDetail.MaterialBarcode = lockobj.MaterialCode;
                    _pickingOrderDetailRepository.AddEntity(pickOrderDetail);
                    #endregion
                    result = _unitOfWork.SaveChangesEntity();
                    if (result)
                    {
                        #region 堆垛机
                        if (Config.IsDev == false)//在测试环境不调用堆垛机
                        {
                            var wcsApiRes = wcsHttp.OutTaskApi(new WcsTaskApiReq()
                            {
                                TaskCode = pickOrder.Code,
                                CellCode = cellobj.Erpcode,
                                PalletCode = pickOrder.PalletBarcode
                            });
                            if (wcsApiRes.Code != 0)
                            {
                                message = wcsApiRes.Msg;
                                _unitOfWork.RollbackChanges();
                                return false;
                            }
                        }
                        #endregion
                        message = "操作成功！";
                        _unitOfWork.CommitChanges();
                    }
                    else
                    {
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                }
                if (result)
                    return true;
                else
                    return false;
            }
            catch (Exception)
            {
                _unitOfWork.RollbackChanges();
                throw;
            }

        }
        */
        #endregion

        private bool StaticFinishShippingOrderDetail(string pickcode, out string message)
        {
            message = "";
            var pickobj = _pickingOrderRepository.QueryEntityWhere(x => x.Code == pickcode && x.SourceType == 2 && x.Status == 4);
            if (pickobj == null)
            {
                message = "找不到下架单！";
                return false;
            }
            var instructlist = _instructRepository.GetEntityWhereAll(x => x.PalletBarcode == pickobj.PalletBarcode && x.Status == 2 && x.InstructType == 2 || (x.PalletBarcode == pickobj.PalletBarcode && x.Status == 2 && x.InstructType == 6)).ToList();
            if (!instructlist.Any())
            {
                message = "未查询到指令！";
                return false;
            }
            var palllist = _palletRepository.GetEntityAll();
            bool result;
            try
            {
                foreach (var instruct in instructlist)
                {
                    var tell = _cellRepository.QueryEntityWhere(x => x.Code == instruct.ExpectedToLocation);
                    if (tell == null)
                    {
                        message = "未查询到仓位！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    instruct.Status = 4;
                    instruct.EndTime = DateTime.Now;
                    _instructRepository.UpdEntity(instruct);

                    //出库单id
                    long? shippid = instruct.RelatedOrderId;
                    if (shippid == null)
                    {
                        message = "出库单明细id有误！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    var shippingOrderDetail = _shippingOrderDetailRepository.QueryEntityById((long)shippid);
                    if (shippingOrderDetail == null)
                    {
                        message = "未查询到单号";
                        return false;
                    }
                    shippingOrderDetail.ShippedQty += instruct.Qty;
                    if (shippingOrderDetail.ShippedQty == shippingOrderDetail.Qty)
                    {
                        shippingOrderDetail.Status = 4;
                        shippingOrderDetail.FinshDate = DateTime.Now;
                    }
                    _shippingOrderDetailRepository.UpdEntity(shippingOrderDetail);

                    if (instruct.RelatedOrderDetailId == null)
                    {
                        message = "出库单明细id有误！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    var lockobj = _lockCellRepository.QueryEntityById((long)instruct.RelatedOrderDetailId);
                    if (lockobj == null)
                    {
                        message = "未查询到单号" + shippingOrderDetail.OrderSn + "的出库单详情";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    lockobj.InventoryQty -= instruct.Qty;
                    lockobj.Status = 4;
                    //拿到库存id
                    long? invid = lockobj.InventoryId;
                    if (invid == null)
                    {
                        message = "出库明细中库存id有误！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    Inventory? inventoryModel = _inventoryRepository.QueryEntityById((long)invid);
                    if (inventoryModel == null)
                    {
                        message = "未查询到库存信息！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    decimal? startQty = inventoryModel.AvailableQty;
                    decimal? changeQty = instruct.Qty;
                    // 库存数量减去需要出库的数量
                    if (inventoryModel.AvailableQty - instruct.Qty == 0)
                    {
                        _inventoryRepository.DelEntity(inventoryModel);
                        result = _unitOfWork.SaveChangesEntity();
                        if (!result)
                        {
                            message = "库存删除失败！";
                            _unitOfWork.RollbackChanges();
                            return false;
                        }
                        var idobj = _inventoryDetailRepository.QueryEntityWhere(x => x.InventoryId == inventoryModel.Id);
                        if (idobj != null)
                            _inventoryDetailRepository.DelEntity(idobj);
                        var pallobj = palllist.FirstOrDefault(x => x.LocationCode == tell.Code && x.LocationName == tell.Name);
                        //查看托上是否还要其他出库的物料 如果有则需要回流
                        var invpal = _inventoryRepository.QueryEntityWhere(x => x.PalletBarcode == instruct.PalletBarcode && x.Status == 4);
                        if (invpal == null)
                        {
                            tell.FullStatus = 0;
                            tell.IsLock = false;
                            tell.BusinessType = 0;
                            tell.ModifyDate = DateTime.Now;
                            tell.Status = 1;
                            _cellRepository.UpdEntity(tell);
                            if (pallobj != null)
                            {
                                pallobj.LocationName = string.Empty;
                                pallobj.LocationCode = string.Empty;
                            }
                        }
                        else
                        {
                            Instruct instruct2 = new Instruct
                            {
                                Status = 2,
                                WarehouseCode = invpal.WarehouseCode,
                                ToLocation = invpal.LocationCode,
                                WorkDeviceType = 1,
                                InstructType = 7,
                                Action = 0,
                                RelatedOrderId = invpal.RelatedOrderDetailId,
                                ExpectedToLocation = invpal.LocationCode,
                                InstructIndex = 1,
                                PalletBarcode = invpal.PalletBarcode,
                                Priority = 9999,
                                Qty = (decimal)invpal.AvailableQty,
                                BusinessType = (int)EmBusinessType.In,
                            };
                            _instructRepository.AddEntity(instruct2);
                            string str = DateTime.Now.ToString("yyyyMMddHHmmssfff");
                            string putawayCode = "SRT" + str;
                            PutawayOrder putawayOrder = new PutawayOrder()
                            {
                                Id = YitIdHelper.NextId(),
                                Code = putawayCode,
                                BillType = 2,
                                RelatedOrderDetailId = invpal.RelatedOrderDetailId,
                                PalletBarcode = invpal.PalletBarcode,
                                LocationCode = invpal.LocationCode,
                                LocationDepth = invpal.LocationDepth == 0 ? null : invpal.LocationDepth,
                                Status = 4,
                                Qty = invpal.AvailableQty,
                                MaterialId = invpal.MaterialId,
                                MaterialCode = invpal.MaterialCode,
                                MaterialName = invpal.MaterialName,
                                MaterialKeyId = invpal.MaterialKeyId,
                                SourceType = 1,
                                CreateDate = DateTime.Now,
                                Roadway = invpal.RoutewayId.ToString()
                            };

                            _putawayOrderRepository.AddEntity(putawayOrder);
                            result = _unitOfWork.SaveChangesEntity();
                            if (!result)
                            {
                                message = "保存上架单失败！";
                                _unitOfWork.RollbackChanges();
                                return false;
                            }
                            //上架单明细表保存
                            PutawayOrderDetail putawayOrderDetail = new PutawayOrderDetail()
                            {
                                Id = YitIdHelper.NextId(),
                                PutawayOrderId = putawayOrder.Id,
                                PalletBarcode = invpal.PalletBarcode,
                            };
                            _putawayOrderDetailRepository.AddEntity(putawayOrderDetail);
                        }
                    }
                    else
                    {
                        inventoryModel.AvailableQty -= instruct.Qty;
                        inventoryModel.IsLock = false;
                        _inventoryRepository.UpdEntity(inventoryModel);
                        if (shippingOrderDetail.BillType == 2)
                        {
                            Instruct instruct2 = new Instruct
                            {
                                Status = 2,
                                WarehouseCode = inventoryModel.WarehouseCode,
                                ToLocation = inventoryModel.LocationCode,
                                WorkDeviceType = 1,
                                InstructType = 7,
                                Action = 0,
                                RelatedOrderId = inventoryModel.RelatedOrderDetailId,
                                ExpectedToLocation = inventoryModel.LocationCode,
                                InstructIndex = 1,
                                PalletBarcode = inventoryModel.PalletBarcode,
                                Priority = 9999,
                                Qty = (decimal)inventoryModel.AvailableQty,
                                BusinessType = (int)EmBusinessType.In,
                            };
                            _instructRepository.AddEntity(instruct2);
                            string str = DateTime.Now.ToString("yyyyMMddHHmmssfff");
                            string putawayCode = "SRT" + str;
                            PutawayOrder putawayOrder = new PutawayOrder();
                            putawayOrder.Id = YitIdHelper.NextId();
                            putawayOrder.Code = putawayCode;
                            putawayOrder.BillType = 2;
                            putawayOrder.RelatedOrderDetailId = inventoryModel.RelatedOrderDetailId;
                            putawayOrder.PalletBarcode = inventoryModel.PalletBarcode;
                            putawayOrder.LocationCode = inventoryModel.LocationCode;
                            putawayOrder.LocationDepth = inventoryModel.LocationDepth == 0 ? null : inventoryModel.LocationDepth;
                            putawayOrder.Status = 4;
                            putawayOrder.Qty = inventoryModel.AvailableQty;
                            putawayOrder.MaterialId = inventoryModel.MaterialId;
                            putawayOrder.MaterialCode = inventoryModel.MaterialCode;
                            putawayOrder.MaterialName = inventoryModel.MaterialName;
                            putawayOrder.MaterialKeyId = inventoryModel.MaterialKeyId;
                            putawayOrder.SourceType = 1;
                            putawayOrder.CreateDate = DateTime.Now;
                            putawayOrder.Roadway = inventoryModel.RoutewayId.ToString();

                            _putawayOrderRepository.AddEntity(putawayOrder);
                            result = _unitOfWork.SaveChangesEntity();
                            if (!result)
                            {
                                message = "保存上架单失败！";
                                _unitOfWork.RollbackChanges();
                                return false;
                            }
                            //上架单明细表保存
                            PutawayOrderDetail putawayOrderDetail = new PutawayOrderDetail()
                            {
                                Id = YitIdHelper.NextId(),
                                PutawayOrderId = putawayOrder.Id,
                                PalletBarcode = inventoryModel.PalletBarcode,
                            };
                            _putawayOrderDetailRepository.AddEntity(putawayOrderDetail);
                        }
                    }
                    //库存流水
                    var inventoryLog = new InventoryLog
                    {
                        Id = YitIdHelper.NextId(),
                        SourceType = 1,
                        SourceSn = shippingOrderDetail.OrderSn,
                        WarehouseId = shippingOrderDetail.WarehouseId,
                        WarehouseName = shippingOrderDetail.WarehouseName,
                        AreaName = shippingOrderDetail.AreaName,
                        LocationCode = inventoryModel.LocationCode,
                        PalletBarcode = inventoryModel.PalletBarcode,
                        MaterialId = inventoryModel.MaterialId,
                        MaterialCode = inventoryModel.MaterialCode,
                        MaterialName = inventoryModel.MaterialName,
                        BatchNo = inventoryModel.BatchNo,
                        StartQty = startQty,
                        ChangeQty = -changeQty,
                        EndQty = startQty - changeQty,
                        BaseUnitId = inventoryModel.UnitId,
                        BaseUnitName = inventoryModel.UnitName,
                        CreateDate = DateTime.Now,
                    };
                    _inventoryLogRepository.AddEntity(inventoryLog);
                    result = _unitOfWork.SaveChangesEntity();
                    if (!result)
                    {
                        message = "保存库存流水失败！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                }
                var ilist = _inventoryRepository.GetEntityWhereAll(x => x.PalletBarcode == pickobj.PalletBarcode);
                foreach (var item in ilist)
                {
                    if (item.AreaCode == "1")
                    {
                        item.Status = 1;
                        item.IsLock = false;
                    }
                    else
                    {
                        item.IsLock = false;
                    }
                }
                var picklist = _pickingOrderRepository.GetEntityWhereAll(x => x.SourceType == 2 && x.Status == 4 && x.PalletBarcode == pickobj.PalletBarcode);
                foreach (var item in picklist)
                {
                    item.Status = 5;
                    item.ModifyDate = DateTime.Now;
                    _pickingOrderRepository.UpdEntity(item);
                }

                return _unitOfWork.SaveChangesEntity();
            }
            catch (Exception)
            {
                _unitOfWork.RollbackChanges();
                throw;
            }
        }

        public bool FinishShippingOrderDetail(string putcode, out string message)
        {
            _unitOfWork.BeginTransaction();
            try
            {
                bool result = StaticFinishShippingOrderDetail(putcode, out message);
                if (result)
                {
                    _unitOfWork.CommitChanges();
                    return true;
                }
                _unitOfWork.RollbackChanges();
                return false;
            }
            catch (Exception)
            {
                _unitOfWork.RollbackChanges();
                throw;
            }
        }

        public bool StartPickingShippingOrderDetail(StartInventoryDTO m, out string message)
        {
            message = string.Empty;
            bool result = false;
            //查询是否有此托盘
            var palletBarAll = _palletRepository.QueryEntityWhere(x => x.PalletBarcode == m.PalletCode);
            if (palletBarAll == null)
            {
                message = "未查询到此托盘";
                return false;
            }
            //根据托盘查找库存数据
            var inlist = _inventoryRepository.GetEntityWhereAll(x => x.PalletBarcode == m.PalletCode && x.Status == 4).ToList();
            _unitOfWork.BeginTransaction();
            try
            {
                if (!inlist.Any())
                {
                    message = "未找到库存数据";
                    _unitOfWork.RollbackChanges();
                    return false;
                }
                else
                {
                    var cell = _cellRepository.QueryEntityWhere(x => x.Code == inlist.First().LocationCode);
                    if (cell == null)
                    {
                        message = "仓位不存在！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }

                    foreach (var item in inlist)
                    {
                        Instruct instruct = new Instruct
                        {
                            Status = 2,
                            WarehouseCode = item.WarehouseCode,
                            ToLocation = item.LocationCode,
                            WorkDeviceType = 1,
                            InstructType = 7,
                            Action = 0,
                            RelatedOrderId = item.RelatedOrderDetailId,
                            ExpectedToLocation = item.LocationCode,
                            InstructIndex = 1,
                            PalletBarcode = m.PalletCode,
                            Priority = 9999,
                            Qty = (decimal)item.AvailableQty,
                            BusinessType = (int)EmBusinessType.In,
                        };
                        _instructRepository.AddEntity(instruct);
                        string str = DateTime.Now.ToString("yyyyMMddHHmmssfff");
                        string putawayCode = "SRT" + str;
                        PutawayOrder putawayOrder = new PutawayOrder();
                        putawayOrder.Id = YitIdHelper.NextId();
                        putawayOrder.Code = putawayCode;
                        putawayOrder.BillType = 2;
                        putawayOrder.RelatedOrderDetailId = item.RelatedOrderDetailId;
                        putawayOrder.PalletBarcode = m.PalletCode;
                        putawayOrder.LocationCode = item.LocationCode;
                        putawayOrder.LocationDepth = item.LocationDepth == 0 ? null : item.LocationDepth;
                        putawayOrder.Status = 4;
                        putawayOrder.Qty = item.AvailableQty;
                        putawayOrder.MaterialId = item.MaterialId;
                        putawayOrder.MaterialCode = item.MaterialCode;
                        putawayOrder.MaterialName = item.MaterialName;
                        putawayOrder.MaterialKeyId = item.MaterialKeyId;
                        putawayOrder.SourceType = 1;
                        putawayOrder.CreateDate = DateTime.Now;
                        putawayOrder.Roadway = item.RoutewayId.ToString();

                        _putawayOrderRepository.AddEntity(putawayOrder);
                        result = _unitOfWork.SaveChangesEntity();
                        if (!result)
                        {
                            message = "保存上架单失败！";
                            _unitOfWork.RollbackChanges();
                            return false;
                        }
                        //上架单明细表保存
                        PutawayOrderDetail putawayOrderDetail = new PutawayOrderDetail()
                        {
                            Id = YitIdHelper.NextId(),
                            PutawayOrderId = putawayOrder.Id,
                            PalletBarcode = m.PalletCode,
                        };
                        _putawayOrderDetailRepository.AddEntity(putawayOrderDetail);


                    }
                }
                if (result)
                {
                    _unitOfWork.CommitChanges();
                    return true;
                }
                _unitOfWork.RollbackChanges();
                return false;
            }
            catch (Exception)
            {

                throw;
            }

        }

        private bool StaticFinishPickingShippingOrderDetail(string putcode, out string message)
        {
            message = "";
            string PalletBarcode = "";
            var putobj = _putawayOrderRepository.QueryEntityWhere(x => x.Code == putcode && x.SourceType == 1 && x.Status == 4 && x.BillType == 2);
            if (putobj == null)
            {
                message = "找不到上架单！";
                return false;
            }
            PalletBarcode = putobj.PalletBarcode;
            var instructlist = _instructRepository.GetEntityWhereAll(x => x.PalletBarcode == PalletBarcode && x.Status == 2 && x.InstructType == 1 || (x.PalletBarcode == PalletBarcode && x.Status == 2 && x.InstructType == 7)).ToList();
            if (!instructlist.Any())
            {
                message = "未查询到上架单指令！";
                return false;
            }
            var invobjlist = _inventoryRepository.GetEntityWhereAll(x => x.PalletBarcode == PalletBarcode);
            try
            {
                if (invobjlist.Any())
                {
                    foreach (var item in invobjlist)
                    {
                        item.Status = 1;
                    }
                }
                foreach (var item in instructlist)
                {
                    item.Status = 4;
                    item.EndTime = DateTime.Now;
                    _instructRepository.UpdEntity(item);
                }
                var putlist = _putawayOrderRepository.GetEntityWhereAll(x => x.SourceType == 1 && x.Status == 4 && x.PalletBarcode == PalletBarcode && x.BillType == 2);
                foreach (var item in putlist)
                {
                    item.Status = 5;
                    item.Fifodate = DateTime.Now;
                    _putawayOrderRepository.UpdEntity(item);
                }
                return _unitOfWork.SaveChangesEntity();
            }
            catch (Exception)
            {
                _unitOfWork.RollbackChanges();
                throw;
            }

        }

        public bool FinishPickingShippingOrderDetail(string putcode, out string message)
        {
            _unitOfWork.BeginTransaction();
            try
            {
                bool result = StaticFinishPickingShippingOrderDetail(putcode, out message);
                if (result)
                {
                    _unitOfWork.CommitChanges();
                    return true;
                }
                _unitOfWork.RollbackChanges();
                return false;
            }
            catch (Exception)
            {
                _unitOfWork.RollbackChanges();
                throw;
            }
        }

        public StackingReceivingsDto? GetReceivingRoderData(string PalletCode, out string message)
        {
            message = string.Empty;

            var invlist = _inventoryRepository.GetEntityWhereAll(x => x.PalletBarcode == PalletCode && x.Status == 4 && x.IsLock == false);
            if (!invlist.Any())
            {
                message = "找不到库存信息";
                return null;
            }
            var putkobj = _putawayOrderRepository.QueryIsEntityWhere(x => x.PalletBarcode == PalletCode && x.Status == 4);
            if (putkobj != null)
            {
                message = "正在作业中！";
                return null;
            }
            StackingReceivingsDto srmodel = new StackingReceivingsDto();
            srmodel.PallteCode = PalletCode;
            foreach (var item in invlist)
            {
                if (item.RelatedOrderDetailId == null)
                {
                    message = "组垛入库关联id有误！";
                    return null;
                }
                srmodel.Cell = item.LocationCode;

                MaterNum maternum = new MaterNum();
                maternum.MaterialCode = item.MaterialCode;
                maternum.Num = item.AvailableQty;
                srmodel.materNum.Add(maternum);
            }

            return srmodel;
        }

        public bool StartShippingOutZeroQty(List<SubmitOutListDTO> OrderDTO, out string message)
        {
            message = string.Empty;
            try
            {
                bool result = false;
                _unitOfWork.BeginTransaction();

                foreach (var item in OrderDTO)
                {
                    //托盘条码
                    string pacode = item.PalletBarcode;

                    Inventory? inventoryModel = _inventoryRepository.QueryEntityById(item.OrderDetId);
                    //状态修改出库在途         
                    if (inventoryModel == null)
                    {
                        message = "获取库存信息失败！";
                        return false;
                    }
                    inventoryModel.Status = 4;
                    var inventorylist = _inventoryRepository.GetEntityWhereAll(x => x.PalletBarcode == pacode && (x.Status == 1 || x.Status == 5));
                    if (inventorylist.Any())
                    {
                        foreach (var item2 in inventorylist)
                        {
                            item2.IsLock = true;
                            item2.Status = 4;
                            _inventoryRepository.UpdEntity(item2);
                        }
                    }
                    var cellobj = _cellRepository.QueryEntityWhere(x => x.Code == inventoryModel.LocationCode);
                    if (cellobj == null)
                    {
                        message = "未查询到仓位" + inventoryModel.LocationCode;
                    }

                    #region 添加指令
                    Instruct inobj = new Instruct();
                    inobj.WarehouseCode = inventoryModel.WarehouseCode;
                    inobj.Status = 2;
                    inobj.FromLocation = item.StationCode;
                    inobj.ToLocation = inventoryModel.LocationCode;
                    inobj.WorkDeviceType = 1;
                    inobj.InstructType = 6;
                    inobj.Action = 0;
                    inobj.RelatedOrderId = 0;
                    inobj.ExpectedToLocation = inventoryModel.LocationCode;
                    inobj.InstructIndex = 1;
                    inobj.PalletBarcode = pacode;
                    inobj.ScanedBarcode = pacode;
                    inobj.Priority = 9999;
                    inobj.Qty = 0;
                    inobj.FinishedQty = 0;
                    inobj.BusinessType = (int)EmBusinessType.Out;
                    inobj.RelatedOrderDetailId = 0;
                    _instructRepository.AddEntity(inobj);
                    #endregion
                    #region 添加下架单
                    string str = DateTime.Now.ToString("yyyyMMddHHmmssfff");
                    string pickCode = "ORT" + str;
                    PickingOrder pickOrder = new PickingOrder();
                    pickOrder.Id = YitIdHelper.NextId();
                    pickOrder.Code = pickCode;
                    pickOrder.WarehouseCode = inventoryModel.WarehouseCode;
                    pickOrder.WarehouseName = inventoryModel.WarehouseName;
                    pickOrder.BillType = 2;
                    pickOrder.DescAddress = item.DescAddress;
                    pickOrder.PalletBarcode = pacode;
                    pickOrder.Roadway = cellobj.RoutewayId.ToString();
                    pickOrder.LocationCode = cellobj.Code;
                    pickOrder.LocationDepth = cellobj.DepthIndex;
                    pickOrder.Status = 4;
                    pickOrder.Qty = 0;
                    pickOrder.MaterialId = inventoryModel.MaterialId;
                    pickOrder.MaterialCode = inventoryModel.MaterialCode;
                    pickOrder.MaterialName = inventoryModel.MaterialName;
                    pickOrder.MaterialKeyId = inventoryModel.MaterialKeyId;
                    pickOrder.BatchNo = inventoryModel.BatchNo;
                    pickOrder.SourceType = 2;
                    pickOrder.RelatedOrderDetailId = 0;
                    pickOrder.CreateDate = DateTime.Now;
                    var pickobj = _pickingOrderRepository.QueryEntityWhere(x => x.PalletBarcode == pacode && x.Status == 4 && x.SourceType == 2);
                    if (pickobj == null)
                    {
                        #region 堆垛机
                        ////获取巷道节点
                        //RoadwayCode roadwayCode = new RoadwayCode()
                        //{
                        //    taskCode = putawayOrder.Code,
                        //    Roadway = putawayOrder.Roadway,
                        //};

                        //var data = HttpHelper.SendPostRequestes("获取巷道节点", roadwayCode);
                        ////LogHelper.LogInformation("巷道节点" + data);
                        ////堆垛机出库
                        //TaskLiku taskLiku = new TaskLiku()
                        //{
                        //    taskCode = putawayOrder.Code,
                        //    taskType = "2",
                        //    startPoint = putawayOrder.LocationCode,
                        //    //endPositionId = OrderDTO.StationCode,
                        //    endPoint = data.data
                        //};
                        ////堆垛机出库和led屏幕显示
                        //var ip = LedipShow.Getledip(putawayOrder.SourceType, putawayOrder.Roadway);
                        //var start = putawayOrder.SourceType == 2 ? "出库" : "入库";
                        //var ledlik = HttpHelper.LedSendPostRequest(new { ip = ip, message = "物料号:" + putawayOrder.MaterialCode + "\\n" + "托盘码" + putawayOrder.PalletBarcode + "\\n" + "状态:" + start + "\\n位置:" + putawayOrder.SiteCode });
                        //var taskLikudata = HttpHelper.WCSSendPostRequest("Api/ApiWCS/ReceiveTask", taskLiku);
                        ////LogHelper.LogInformation("wcs出入库：" + taskLikudata);
                        #endregion
                    }
                    _pickingOrderRepository.AddEntity(pickOrder);
                    PickingOrderDetail pickOrderDetail = new PickingOrderDetail();
                    pickOrderDetail.Id = YitIdHelper.NextId();
                    pickOrderDetail.OrderId = pickOrder.Id;
                    pickOrderDetail.PalletBarcode = pacode;
                    pickOrderDetail.MaterialBarcode = inventoryModel.MaterialCode;
                    _pickingOrderDetailRepository.AddEntity(pickOrderDetail);
                    #endregion
                    result = _unitOfWork.SaveChangesEntity();
                    if (!result)
                    {
                        message = "出库解绑失败";
                        return false;
                    }
                }
                if (result)
                {
                    message = "操作成功！";
                    _unitOfWork.CommitChanges();
                    return true;
                }
                _unitOfWork.RollbackChanges();
                return false;
            }
            catch (Exception)
            {
                _unitOfWork.RollbackChanges();
                throw;
            }
        }

        private bool StaticFinishShippingOutZeroQty(string pickcode, out string message)
        {
            message = "";
            string PalletBarcode = "";
            var pickobj = _pickingOrderRepository.QueryEntityWhere(x => x.Code == pickcode && x.SourceType == 2 && x.Status == 4 && x.BillType == 2);
            if (pickobj == null)
            {
                message = "找不到下架单！";
                return false;
            }
            PalletBarcode = pickobj.PalletBarcode;
            var instructlist = _instructRepository.GetEntityWhereAll(x => x.PalletBarcode == PalletBarcode && x.Status == 2 && x.InstructType == 6).ToList();
            if (!instructlist.Any())
            {
                message = "未查询到上架单指令！";
                return false;
            }
            try
            {
                foreach (var item in instructlist)
                {
                    item.Status = 4;
                    item.EndTime = DateTime.Now;
                    _instructRepository.UpdEntity(item);
                }
                var ilist = _inventoryRepository.GetEntityWhereAll(x => x.PalletBarcode == PalletBarcode && x.Status == 4).ToList();
                if (ilist.Any())
                {
                    foreach (var item in ilist)
                    {
                        item.IsLock = false;
                        _inventoryRepository.UpdEntity(item);
                    }
                }
                var picklist = _pickingOrderRepository.GetEntityWhereAll(x => x.SourceType == 2 && x.Status == 4 && x.PalletBarcode == PalletBarcode && x.BillType == 2);
                foreach (var item in picklist)
                {
                    item.Status = 5;
                    //item.Fifodate = DateTime.Now;
                    _pickingOrderRepository.UpdEntity(item);
                }
                return _unitOfWork.SaveChangesEntity();
            }
            catch (Exception)
            {
                _unitOfWork.RollbackChanges();
                throw;
            }
        }

        public bool FinishShippingOutZeroQty(string pickcode, out string message)
        {
            _unitOfWork.BeginTransaction();
            try
            {
                bool result = StaticFinishShippingOutZeroQty(pickcode, out message);
                if (result)
                {
                    _unitOfWork.CommitChanges();
                    return true;
                }
                _unitOfWork.RollbackChanges();
                return false;
            }
            catch (Exception)
            {
                _unitOfWork.RollbackChanges();
                throw;
            }
        }
        #endregion

        #region 速锐WCS取消任务,弃用最新在撤销指令当中
        public bool WCSCancelTask(string pallCode, out string message)
        {
            _unitOfWork.BeginTransaction();
            try
            {
                bool result = CancelTaskOutboundShipments(pallCode, out message);
                if (result)
                {
                    _unitOfWork.CommitChanges();
                    return true;
                }
                _unitOfWork.RollbackChanges();
                return false;
            }
            catch (Exception)
            {
                _unitOfWork.RollbackChanges();
                throw;
            }
        }
        
        private bool CancelTaskOutboundShipments(string pallCode, out string message)
        {
            //取消出库任务是需要判断本次出库任务后面仓位是否有任务，如果有任务就需要将本次取消出库任务变成移库任务不能挡住后面出库任务
            message = "";
            //bool result = false;
            try
            {
                var pallData = _palletRepository.QueryEntityWhere(p=>p.PalletBarcode == pallCode);
                if (pallData == null)
                {
                    message = "未查询到托盘!";
                    return false;
                }
               
                //根据托盘去查询出出库单明细 (一个托盘可能会存在多个明细如果取消则都需要取消)
                var lockCellList = _lockCellRepository.GetEntityWhereAll(l => l.PalletBarcode == pallCode && l.Status == 3).ToList();
                if (!lockCellList.Any())
                {
                    message = "未查询到出库单明细信息!";
                    return false;
                }

                var cellData = _cellRepository.QueryEntityWhere(c => c.Code == pallData.LocationCode);
                if (cellData == null)
                {
                    message = "未查询到仓位!";
                    return false;
                }

                string pickingCode = null;

                foreach (var lockCell in lockCellList)
                {

                    if (cellData.Code != lockCell.CellCode)
                    {
                        message = "出库仓位和托盘所在仓位不是同一个仓位!";
                        return false;
                    }

                    //修改出库单明细状态
                    lockCell.Status = 0;
                    _lockCellRepository.UpdEntity(lockCell);

                    //查询出库单
                    var shippingOrder = _shippingOrderDetailRepository.QueryEntityWhere(s => s.Id == lockCell.OrderDetailId);
                    if (shippingOrder == null)
                    {
                        message = "未查询到出库单!";
                        return false;
                    }
                    shippingOrder.Status = 0;
                    _shippingOrderDetailRepository.UpdEntity(shippingOrder);

                    //将库存数据改成正常
                    var inventory = _inventoryRepository.QueryEntityWhere(x => x.PalletBarcode == pallCode && x.Status == 4 && x.IsLock == true);
                    if (inventory == null)
                    {
                        message = "未查询到库存数据!";
                        return false;
                    }
                    inventory.IsLock = true; //状态还是锁住的状态
                    inventory.Status = 1;

                    //查询指令
                    var instruct = _instructRepository.QueryEntityWhere(x => x.PalletBarcode == lockCell.PalletBarcode && x.Status == 2 && x.InstructType == 2 || (x.PalletBarcode == lockCell.PalletBarcode && x.Status == 2 && x.InstructType == 6));
                    if (instruct == null)
                    {
                        message = "未查询到指令任务!";
                        return false;
                    }
                    _instructRepository.DelEntity(instruct);

                    var picking = _pickingOrderRepository.QueryEntityWhere(p => p.PalletBarcode == pallCode && p.Status == 4);
                    if (picking == null)
                    {
                        message = "未查询到下架单";
                        return false;
                    }
                    pickingCode = pickingCode ?? picking.Code;
                    _pickingOrderRepository.DelEntity(picking);

                    var pickingDetail = _pickingOrderDetailRepository.QueryEntityWhere(p => p.OrderId == picking.Id);
                    if (pickingDetail == null)
                    {
                        message = "未查询到下架单明细";
                        return false;
                    }
                    _pickingOrderDetailRepository.DelEntity(pickingDetail);
                    _unitOfWork.SaveChangesEntity();
                }

                CancelTaskData cancelTaskData = new CancelTaskData();
                cancelTaskData.MsgTime = DateTime.Now.ToString();
                cancelTaskData.TaskId = pickingCode;
                if (Config.IsDev == false)
                {
                    var newWcsApi = wcsHttp.CancelTaskApi(cancelTaskData);
                    if (newWcsApi.returnStatus == 1)
                    {
                        message = "取消任务失败," + newWcsApi.returnInfo;
                        return false;
                    }
                }
                //使用三元表达式，来判断查询条件
                var depthCell = cellData.LineNo > 4 ? _cellRepository.GetEntityWhereAll(c => c.LayerNo == cellData.LayerNo && c.ColumnNo == cellData.ColumnNo && c.LineNo > cellData.LineNo && c.LineNo > 4).OrderBy(c => c.DepthIndex).ToList() : _cellRepository.GetEntityWhereAll(c => c.LayerNo == cellData.LayerNo && c.ColumnNo == cellData.ColumnNo && c.LineNo < cellData.LineNo && c.LineNo < 4).OrderBy(c => c.DepthIndex).ToList();

                #region 判断是否需要把本次任务换成移库任务
                bool WhetherTransferBin = false;
                foreach (var decell in depthCell)
                {
                    //这里还能是移库和出库任务 如果取消任务后面的仓位有任务就将本次取消任务给换成移库
                    var transferBinTaks = _putawayOrderRepository.QueryEntityWhere(p => p.LocationCode == decell.Code && p.Status == 4 && p.SourceType == 3);
                    if (transferBinTaks != null)
                    {
                        WhetherTransferBin = true;
                        break;
                    }
                    //查询是否有出库任务
                    var outTaks = _pickingOrderRepository.QueryEntityWhere(p => p.LocationCode == decell.Code && p.Status == 4 && p.SourceType == 2);
                    if (outTaks != null)
                    {
                        WhetherTransferBin = true;
                        break;
                    }
                }
                if (WhetherTransferBin)
                {
                    //传入的是需要移库的仓位数据而不是出库仓位数据
                    var transCellData = ShippingTransferBinInventory(cellData.LayerNo, cellData.Code, cellData.AreaCode, out message);
                    if (transCellData == null)
                    {
                        message = "创建移库任务失败，" + message;
                        return false;
                    }

                    //查询移库单
                    var putaway = _putawayOrderRepository.QueryEntityWhere(p => p.Status == 4 && p.LocationCode == transCellData.Code && p.SourceType == 3);
                    if (putaway == null)
                    {
                        message = "未查询到移库任务!";
                        return false;
                    }
                    //在将取消的任务下发成移库任务 注意要将优先级提高
                    TaskAccept taskAccept = new TaskAccept
                    {
                        tasks = new List<Tasks>()
                        {
                            new Tasks()
                            {
                                TaskId = putaway.Code,
                                TaskType = 2,
                                BarCode = putaway.PalletBarcode,
                                EndNode = putaway.LocationCode,
                                StartNode = cellData.Code,
                                Order = 1
                            }
                        },
                        Warehouse = Config.WMSWarehouseCode,
                        GroupId = Guid.NewGuid().ToString("N"),
                        MsgTime = DateTime.Now.ToString(),
                        PriorityCode = 80 //优先级80
                    };

                   
                    if (Config.IsDev == false)
                    {
                        //wcs返回结果
                        var Wcsresult = wcsHttp.TaskAcceptApi(taskAccept);
                        if (Wcsresult.returnStatus != 0)
                        {
                            message = "下发移库任务失败，" + Wcsresult.returnInfo;
                            return false;
                        }
                    }
                    return true;
                }
                #endregion
                return true;
            }
            catch (Exception ex)
            {
                _unitOfWork.RollbackChanges();
                throw;
            }
        }

        #endregion

        public bool EBSAddShippingOrderDetail(EBSShippingOrderDTO eBSShippingOrder, out string message)
        {
            message = string.Empty;
            ShippingOrderDetail shippingOrderDetail = new();
            shippingOrderDetail.OrderSn = eBSShippingOrder.OrderSn;
            shippingOrderDetail.Status = 0;
            shippingOrderDetail.SourceType = eBSShippingOrder.BillType;
            shippingOrderDetail.CreateDate = DateTime.Now;
            shippingOrderDetail.ModifyDate = DateTime.Now;
            shippingOrderDetail.CreateUserId = 0;
            shippingOrderDetail.ShippedQty = 0;
            shippingOrderDetail.IsDel = false;
            shippingOrderDetail.IsSuspend = false;
            //是否挂起-逻辑待处理
            try
            {
                _unitOfWork.BeginTransaction();
                foreach (var item in eBSShippingOrder.items)
                {
                    //将库存物料全部查询出来根据库存数量和仓位深度来排序
                    var inventoryList = _inventoryRepository.GetEntityWhereAll(i=>i.Status == 1 && i.IsLock == false && i.MaterialCode == item.MaterialCode).OrderBy(i=>i.LocationDepth).OrderByDescending(i => i.AvailableQty).ToList();
                    if (inventoryList.Count() <= 0)
                    {
                        message = "找不到库存信息！" + item.MaterialName;
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    //首先判断库存数量是否够出
                    var inventoryMaterialCount = inventoryList.Sum(i=>i.AvailableQty);
                    if (inventoryMaterialCount < item.OutQty)
                    {
                        message = item.MaterialName + "库存数量不足,目前库存数量为" + inventoryMaterialCount;
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    decimal? OutQtyData = item.OutQty;
                    foreach (var inventory in inventoryList)
                    {
                        ShippingLockCell shippingLockCell = new();
                        shippingLockCell.MaterialCode = item.MaterialCode;
                        shippingLockCell.MaterialName = item.MaterialName;
                        shippingLockCell.Status = 0;
                        shippingLockCell.CreateDate = DateTime.Now;
                        shippingLockCell.CreateUserId = 0;
                        shippingLockCell.IsDel = false;
                        if (OutQtyData -inventory.AvailableQty == 0)//如果库存数量等于出库数量则为直出
                        {
                            inventory.PickedQty += inventory.AvailableQty;
                            inventory.IsLock = true;
                            shippingOrderDetail.BillType = 1;
                            shippingLockCell.OutQty = inventory.AvailableQty; //当前库存数量等于出库数量时出库数量为库存数量
                        }
                        if (OutQtyData - inventory.AvailableQty < 0) //如果库存数量大于出库数量则为拣选出库
                        {
                            inventory.PickedQty += OutQtyData;
                            inventory.IsLock = true;
                            shippingOrderDetail.BillType = 2;
                            shippingLockCell.OutQty = OutQtyData; //库存数量大于出库数量时为出库数量为出库数量
                        }
                        if (OutQtyData - inventory.AvailableQty > 0)//当前库存数量小于出库数量则为直出但是需要进行下个库存
                        {

                            inventory.PickedQty += inventory.AvailableQty;
                            inventory.IsLock = true;
                            shippingOrderDetail.BillType = 1;
                            shippingLockCell.OutQty = inventory.AvailableQty; //当前库存数量小于出库数量时出库数量为库存数量
                        }
                        OutQtyData -= inventory.AvailableQty; //减去本次出库库存数量

                        #region 出库单字段和库存字段修改
                        shippingOrderDetail.AreaCode = inventory.AreaCode;
                        shippingOrderDetail.AreaName = inventory.AreaName;
                        shippingOrderDetail.WarehouseId = inventory.WarehouseId;
                        shippingOrderDetail.WarehouseCode = inventory.WarehouseCode;
                        shippingOrderDetail.WarehouseName = inventory.WarehouseName;
                        shippingOrderDetail.MaterialId = inventory.MaterialId == null ? 0 : Convert.ToInt64(inventory.MaterialId);
                        shippingOrderDetail.MaterialName = inventory.MaterialName;
                        shippingOrderDetail.MaterialCode = inventory.MaterialCode;
                        shippingOrderDetail.MaterialTypeCode = inventory.MaterialTypeCode;
                        shippingOrderDetail.UnitId = inventory.UnitId;
                        shippingOrderDetail.UnitName = inventory.UnitName;
                        shippingOrderDetail.Qty = shippingLockCell.OutQty;
                        shippingOrderDetail.BatchNo = inventory.BatchNo;
                        _shippingOrderDetailRepository.AddEntity(shippingOrderDetail);
                        if (!_unitOfWork.SaveChangesEntity())
                        {
                            message = "添加出库单失败";
                            _unitOfWork.RollbackChanges();
                            return false;
                        }
                        #endregion

                        #region 出库单明细添加
                        shippingLockCell.IsPicking = true;
                        shippingLockCell.OrderDetailId = shippingOrderDetail.Id;
                        shippingLockCell.OrdeSn = shippingOrderDetail.OrderSn;
                        shippingLockCell.InventoryId = inventory.Id;
                        shippingLockCell.CellId = inventory.LocationId;
                        shippingLockCell.CellCode = inventory.LocationCode;
                        shippingLockCell.CellName = inventory.LocationName;
                        shippingLockCell.CellDepthIndex = inventory.LocationDepth;
                        shippingLockCell.WhId = inventory.WarehouseId;
                        shippingLockCell.PalletBarcode = inventory.PalletBarcode;
                        shippingLockCell.MaterialId = inventory.MaterialId;
                        shippingLockCell.MaterialCode = inventory.MaterialCode;
                        shippingLockCell.MaterialName = inventory.MaterialName;
                        shippingLockCell.MaterialKeyId = inventory.MaterialKeyId;
                        shippingLockCell.RoutewayId = inventory.RoutewayId;
                        shippingLockCell.BatchNo = inventory.BatchNo;
                        shippingLockCell.InventoryQty = inventory.AvailableQty;
                        if (shippingLockCell.OutQty == 0)
                        {
                            message = "出库数量不能为0！";
                            _unitOfWork.RollbackChanges();
                            return false;
                        }
                        if (shippingLockCell.OutQty > inventory.AvailableQty)
                        {
                            message = "出库数量不能大于库存可用数量！" + inventory.AvailableQty;
                            _unitOfWork.RollbackChanges();
                            return false;
                        }
                        if (shippingLockCell.OutQty % 1 != 0)
                        {
                            message = "出库数量不能是小数";
                            _unitOfWork.RollbackChanges();
                            return false;
                        }
                        _lockCellRepository.AddEntity(shippingLockCell);
                        _inventoryRepository.UpdEntity(inventory);
                        if (!_unitOfWork.SaveChangesEntity())
                        {
                            message = "添加出库单失败";
                            _unitOfWork.RollbackChanges();
                            return false;
                        }

                        #endregion

                        if (OutQtyData <= 0)
                        {
                            break;
                        }
                    }
                }
                _unitOfWork.CommitChanges();
                return true;
            }
            catch (Exception)
            {
                _unitOfWork.RollbackChanges();
                throw;
            }

        }
    }
}
